From 40ee61a686826ac8e937af720bc152895b10392b Mon Sep 17 00:00:00 2001 From: Emmanuele Bassi Date: Wed, 22 Jun 2016 10:56:27 +0100 Subject: [PATCH] gtk: Keep Firefox working in the DrawingContext world MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit Firefox does a bunch of interesting things with GTK. If the top-level GtkWindow does not have a "csd" style class associated, Firefox will happily draw the contents of the container used to render HTML and XUL directly on the top level's GdkWindow; on the other hand, if a "csd" style class is found, the MozContainer will create a new child window, and draw on it. Then, Firefox will proceed to disable double buffering on both the top-level window and the MozContainer (unless they are backed by the same GdkWindow, in which case only the top-level will be single-buffered) *and* it will add a GDK_EXPOSURE_MASK flag to the MozContainer events for good measure (even if this is only needed for GTK+ 2.x). After landing the GdkDrawingContext API in GdkWindow, GTK enabled automatic double buffering on all top-level windows backed by a native surface, ad most users of single buffering rely on child widgets instead of top-levels, and we'd still like to have the same double buffering behaviour for all top-levels on all backends. Obviously, with Firefox disabling double buffering on the top-level window, the change broke their drawing mechanism. Ideally, Firefox could be fixed to not disable double buffering on the top-level window when MozContainer has a separate GdkWindow — i.e. the CSD case — but since we did introduce a slight change of behaviour in fringe users of the GTK+ API, let's keep backwards compatibility with the old code for a little while longer, and create an intermediate Cairo context unbound from the GdkDrawingContext, like we used to do until GTK+ 3.20. --- gtk/gtkwidget.c | 23 +++++++++++++++++++---- 1 file changed, 19 insertions(+), 4 deletions(-) diff --git a/gtk/gtkwidget.c b/gtk/gtkwidget.c index e6dfac7ef1..5b87a3338e 100644 --- a/gtk/gtkwidget.c +++ b/gtk/gtkwidget.c @@ -17463,15 +17463,30 @@ gtk_widget_render (GtkWidget *widget, /* We only render double buffered on native windows */ if (!gdk_window_has_native (window)) return; - } - context = gdk_window_begin_draw_frame (window, region); - cr = gdk_drawing_context_get_cairo_context (context); + context = gdk_window_begin_draw_frame (window, region); + cr = gdk_drawing_context_get_cairo_context (context); + } + else + { + /* This is annoying, but it has to stay because Firefox + * disables double buffering on a top-level GdkWindow, + * which breaks the drawing context. + * + * Candidate for deletion in the next major API bump. + */ +G_GNUC_BEGIN_IGNORE_DEPRECATIONS + cr = gdk_cairo_create (window); +G_GNUC_END_IGNORE_DEPRECATIONS + } do_clip = _gtk_widget_get_translation_to_window (widget, window, &x, &y); cairo_translate (cr, -x, -y); gtk_widget_draw_internal (widget, cr, do_clip); - gdk_window_end_draw_frame (window, context); + if (priv->double_buffered) + gdk_window_end_draw_frame (window, context); + else + cairo_destroy (cr); } -- 2.30.2